function enhancCommitlintConfig(fs, path) {
  const enhanceData = `module.exports = { extends: ['@commitlint/config-conventional'] }
  `
  try {
    fs.writeFileSync(path, enhanceData)
  } catch (error) {
    console.error(error)
  }
}

function enhancEslintignore(fs, path) {
  const enhanceData = `# .eslintignore

  src/assets
  src/icons
  public
  dist
  node_modules
  `
  try {
    fs.writeFileSync(path, enhanceData)
  } catch (error) {
    console.error(error)
  }
}

function enhanceEditorconfig(fs, path) {
  const enhanceData = `# Editor configuration, see http://editorconfig.org

  # 表示是最顶层的 EditorConfig 配置文件
  root = true
  
  [*] # 表示所有文件适用
  charset = utf-8 # 设置文件字符集为 utf-8
  indent_style = space # 缩进风格（tab | space）
  indent_size = 2 # 缩进大小
  end_of_line = lf # 控制换行类型(lf | cr | crlf)
  trim_trailing_whitespace = true # 去除行首的任意空白字符
  insert_final_newline = true # 始终在文件末尾插入一个新行
  
  [*.md] # 表示仅 md 文件适用以下规则
  max_line_length = off
  trim_trailing_whitespace = false
  `
  try {
    fs.writeFileSync(path, enhanceData)
  } catch (error) {
    console.error(error)
  }
}

function enhancCzConfig(fs, path) {
  const enhanceData = `module.exports = {
    // type 类型（定义之后，可通过上下键选择）
    types: [
      { value: 'feat', name: 'feat:     新增功能' },
      { value: 'fix', name: 'fix:      修复 bug' },
      { value: 'docs', name: 'docs:     文档变更' },
      { value: 'style', name: 'style:    代码格式（不影响功能，例如空格、分号等格式修正）' },
      { value: 'refactor', name: 'refactor: 代码重构（不包括 bug 修复、功能新增）' },
      { value: 'perf', name: 'perf:     性能优化' },
      { value: 'test', name: 'test:     添加、修改测试用例' },
      { value: 'build', name: 'build:    构建流程、外部依赖变更（如升级 npm 包、修改 webpack 配置等）' },
      { value: 'ci', name: 'ci:       修改 CI 配置、脚本' },
      { value: 'chore', name: 'chore:    对构建过程或辅助工具和库的更改（不影响源文件、测试用例）' },
      { value: 'revert', name: 'revert:   回滚 commit' }
    ],
  
    // scope 类型（定义之后，可通过上下键选择）
    scopes: [
      ['components', '组件相关'],
      ['hooks', 'hook 相关'],
      ['utils', 'utils 相关'],
      ['styles', '样式相关'],
      ['deps', '项目依赖'],
      ['other', '其他修改'],
      // 如果选择 custom，后面会让你再输入一个自定义的 scope。也可以不设置此项，把后面的 allowCustomScopes 设置为 true
      ['custom', '以上都不是？我要自定义']
    ].map(([value, description]) => {
      return {
        value,
        name: \`\${value.padEnd(30)} (\${description})\`
      }
    }),
  
    // 是否允许自定义填写 scope，在 scope 选择的时候，会有 empty 和 custom 可以选择。
    // allowCustomScopes: true,
  
    // allowTicketNumber: false,
    // isTicketNumberRequired: false,
    // ticketNumberPrefix: 'TICKET-',
    // ticketNumberRegExp: '\\d{1,5}',
  
  
    // 针对每一个 type 去定义对应的 scopes，例如 fix
    /*
    scopeOverrides: {
      fix: [
        { name: 'merge' },
        { name: 'style' },
        { name: 'e2eTest' },
        { name: 'unitTest' }
      ]
    },
    */
  
    // 交互提示信息
    messages: {
      type: \`确保本次提交遵循 Angular 规范！\\n选择你要提交的类型：\`,
      scope: \`\\n选择一个 scope（可选）：\`,
      // 选择 scope: custom 时会出下面的提示
      customScope: "请输入自定义的 scope：",
      subject: \`填写简短精炼的变更描述：\\n\`,
      body:
        \`填写更加详细的变更描述（可选）。使用 "|" 换行：\\n\`,
      breaking: \`列举非兼容性重大的变更（可选）：\\n\`,
      footer: \`列举出所有变更的 ISSUES CLOSED（可选）。 例如: #31, #34：\\n\`,
      confirmCommit: '确认提交？'
    },
  
    // 设置只有 type 选择了 feat 或 fix，才询问 breaking message
    allowBreakingChanges: ['feat', 'fix'],
  
    // 跳过要询问的步骤
    skipQuestions: ['body', 'footer'],
  
    // subject 限制长度
    subjectLimit: 100,
    breaklineChar: '|', // 支持 body 和 footer
    // footerPrefix : 'ISSUES CLOSED:'
    // askForBreakingChangeFirst : true,
  }
  `

  try {
    fs.writeFileSync(path, enhanceData)
  } catch (error) {
    console.error(error)
  }
}

function enhancePrettierrc(fs, path) {
  const enhanceData = `{
    "useTabs": false,
    "tabWidth": 2,
    "printWidth": 100,
    "singleQuote": true,
    "trailingComma": "none",
    "bracketSpacing": true,
    "semi": false
  }
  `
  try {
    fs.writeFileSync(path, enhanceData)
  } catch (error) {
    console.error(error)
  }
}

function enhancVscode(fs, path) {
  const enhanceData = `{
    "[vue]": {
      "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "editor.quickSuggestions": {
      "strings": true
    },
    "editor.tabSize": 2,
    "editor.detectIndentation": false,
    "emmet.triggerExpansionOnTab": true,
    "javascript.format.enable": true,
    "git.enableSmartCommit": true,
    "git.autofetch": true,
    "git.confirmSync": false,
    "[json]": {
      "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "liveServer.settings.donotShowInfoMsg": true,
    "explorer.confirmDelete": false,
    "javascript.updateImportsOnFileMove.enabled": "always",
    "typescript.updateImportsOnFileMove.enabled": "always",
    "files.exclude": {
      "**/.idea": true
    },
    "editor.codeActionsOnSave": {
      "source.fixAll.stylelint": true,
      "source.fixAll.eslint": true
    },
    "[javascript]": {
      "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "[jsonc]": {
      "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "[html]": {
      "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "editor.suggest.snippetsPreventQuickSuggestions": false,
    "prettier.htmlWhitespaceSensitivity": "ignore",
    "prettier.vueIndentScriptAndStyle": true,
    "vetur.format.defaultFormatter.html": "prettier",
    "path-intellisense.mappings": {
      "@": "\${workspaceRoot}/src"
    },
    "files.eol": "\\n"
  }
  `

  try {
    fs.mkdirSync(path)
  } catch (error) {
    // console.error(error)
  }
  
  try {
    fs.writeFileSync(`${path}/settings.json`, enhanceData)
  } catch (error) {
    console.error(error)
  }
}

function enhancHusky(fs, path) {
  const commitMsgData = `#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no-install commitlint --edit 
`
  const preCommitData = `#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
`
  try {
    fs.mkdirSync(path)
    fs.writeFileSync(`${path}/.gitignore`, `_
    `)
    fs.mkdirSync(`${path}/_`)
  } catch (error) {
    // console.error(error)
  }
  
  try {
    fs.writeFileSync(`${path}/_/husky.sh`, `#!/bin/sh
    if [ -z "$husky_skip_init" ]; then
      debug () {
        [ "$HUSKY_DEBUG" = "1" ] && echo "husky (debug) - $1"
      }
    
      readonly hook_name="$(basename "$0")"
      debug "starting $hook_name..."
    
      if [ "$HUSKY" = "0" ]; then
        debug "HUSKY env variable is set to 0, skipping hook"
        exit 0
      fi
    
      if [ -f ~/.huskyrc ]; then
        debug "sourcing ~/.huskyrc"
        . ~/.huskyrc
      fi
    
      export readonly husky_skip_init=1
      sh -e "$0" "$@"
      exitCode="$?"
    
      if [ $exitCode != 0 ]; then
        echo "husky - $hook_name hook exited with code $exitCode (error)"
        exit $exitCode
      fi
    
      exit 0
    fi
    `)
    fs.writeFileSync(`${path}/commit-msg`, commitMsgData)
    fs.writeFileSync(`${path}/pre-commit`, preCommitData)
  } catch (error) {
    console.error(error)
  }
}

function enhancEeslintrc(fs, path) {
  const enhanceData = `module.exports = {
    root: true,
    env: {
      node: true
    },
    extends: [
      'plugin:vue/essential',
      '@vue/typescript',
      'plugin:prettier/recommended' // 添加 prettier 插件
    ],
    rules: {
      quotes: [2, 'single'], //单引号
      'new-cap': 'off',
      'no-continue': 'off',
      experimentalDecorators: 'off',
      'consistent-return': 'off',
      'no-plusplus': 'off',
      'guard-for-in': 'off',
      'prefer-destructuring': 'off',
      'prefer-promise-reject-errors': 'off',
      camelcase: 'off',
      'space-infix-ops': 'off',
      'import/prefer-default-export': 'off',
      'no-restricted-syntax': 0,
      'no-restricted-globals': 'off',
      'global-require': 'off',
      'import/no-dynamic-require': 'off',
      'import/no-unresolved': 'off',
      'import/newline-after-import': 'off',
      'import/extensions': 'off',
      'no-param-reassign': 'off',
      'class-methods-use-this': 'off',
      'linebreak-style': ['error', 'unix'], // 将文件更改为 LF
      'no-console': 0, //不禁用console
      // "no-debugger": 2, //禁用debugger
      'no-var': 0, //对var警告
      semi: 0, //不强制使用分号
      'no-irregular-whitespace': 0, //不规则的空白不允许
      'no-trailing-spaces': 1, //一行结束后面有空格就发出警告
      'eol-last': 0, //文件以单一的换行符结束
      'no-underscore-dangle': 0, //标识符不能以_开头或结尾
      'no-alert': 2, //禁止使用alert confirm prompt
      'no-lone-blocks': 0, //禁止不必要的嵌套块
      'no-class-assign': 2, //禁止给类赋值
      'no-cond-assign': 2, //禁止在条件表达式中使用赋值语句
      'no-const-assign': 2, //禁止修改const声明的变量
      'no-delete-var': 2, //不能对var声明的变量使用delete操作符
      'no-dupe-keys': 2, //在创建对象字面量时不允许键重复
      'no-duplicate-case': 2, //switch中的case标签不能重复
      'no-dupe-args': 2, //函数参数不能重复
      'no-empty': 2, //块语句中的内容不能为空
      'no-func-assign': 2, //禁止重复的函数声明
      'no-invalid-this': 0, //禁止无效的this，只能用在构造器，类，对象字面量
      'no-redeclare': 2, //禁止重复声明变量
      'no-spaced-func': 2, //函数调用时 函数名与()之间不能有空格
      'no-this-before-super': 0, //在调用super()之前不能使用this或super
      'no-undef': 2, //不能有未定义的变量
      'no-use-before-define': 2, //未定义前不能使用
      'use-isnan': 2, // 要求使用 isNaN() 检查 NaN
      'jsx-quotes': [2, 'prefer-double'], //强制在JSX属性（jsx-quotes）中一致使用双引号
      'vue/attribute-hyphenation': ['error', 'always'],
      'vue/html-end-tags': 'error',
      'vue/html-indent': ['error', 2],
      'vue/html-self-closing': [
        'error',
        {
          html: {
            void: 'always',
            normal: 'never',
            component: 'always'
          },
          svg: 'always',
          math: 'always'
        }
      ],
      'vue/script-setup-uses-vars': 0, // vue3 可放开
      'vue/require-default-prop': 'error',
      'vue/require-prop-types': 'error',
      'vue/attributes-order': 'error',
      'vue/order-in-components': 'error'
    },
    parserOptions: {
      parser: '@typescript-eslint/parser'
    }
  }
  `
  try {
    fs.writeFileSync(path, enhanceData)
  } catch (error) {
    console.error(error)
  }
}

module.exports = (api, options, rootOptions) => {
  api.extendPackage({
    "scripts": {
      "lint": "eslint --ext '.js,.vue,.ts' src",
      "lint:fix": "eslint --fix --ext '.js,.vue,.ts' src",
      "commit": "npx cz",
      "prepare": "husky install"
    },
    "lint-staged": {
      "*.{vue,js,ts}": "eslint --fix"
    },
    "devDependencies": {
      "prettier": "2.2.1",
      "eslint": "^7.30.0",
      "eslint-plugin-vue": "^7.13.0",
      "@typescript-eslint/eslint-plugin": "4.28.0",
      "@typescript-eslint/parser": "4.28.0",
      "eslint-config-airbnb-base": "^14.2.1",
      "eslint-plugin-import": "^2.23.4",
      "eslint-config-prettier": "8.3.0",
      "eslint-plugin-prettier": "3.4.0",
      "@vue/eslint-config-typescript": "^4.0.0",
      "husky": "^7.0.0",
      "lint-staged": "10.5.4",
      "commitizen": "4.2.3",
      "cz-conventional-changelog": "3.3.0",
      "cz-customizable": "6.3.0",
      "@commitlint/config-conventional": "12.1.1",
      "@commitlint/cli": "12.1.1",
    },
    "config": {
      "commitizen": {
        "path": "./node_modules/cz-customizable"
      }
    }
  });

  api.onCreateComplete(() => {
    const fs = require('fs');

    // .editorconfig
    const editorconfigPath = api.resolve('./.editorconfig');
    enhanceEditorconfig(fs, editorconfigPath)
    // .prettierrc
    const prettierrcPath = api.resolve('./.prettierrc');
    enhancePrettierrc(fs, prettierrcPath)
    // .eslintrc.js
    const eslintrcPath = api.resolve('./.eslintrc.js');
    enhancEeslintrc(fs, eslintrcPath)
    // .eslintignore
    const eslintignorePath = api.resolve('./.eslintignore');
    enhancEslintignore(fs, eslintignorePath)
    // .husky
    const huskyPath = api.resolve('./.husky');
    enhancHusky(fs, huskyPath)
    // .cz-config.js
    const czConfigPath = api.resolve('./.cz-config.js');
    enhancCzConfig(fs, czConfigPath)
    // commitlint.config.js
    const commitlintConfigPath = api.resolve('./commitlint.config.js');
    enhancCommitlintConfig(fs, commitlintConfigPath)
    // .vscode
    const vscodePath = api.resolve('./.vscode');
    enhancVscode(fs, vscodePath)
  });

}
